#include "recvaudio.h"

RecvAudio::RecvAudio(QObject *parent)
    :QThread(parent)
{
    m_PCMDataBuffer.clear();

    udpsocket = new QUdpSocket(this);
}


RecvAudio::~RecvAudio()
{
    delete udpsocket;
    delete m_OutPut;
    delete m_AudioIo;
}


void RecvAudio::setCurrentVolumn(qreal volumn){
    m_OutPut->setVolume(volumn);
}

void RecvAudio::init(int quality, int port)
{
    udpsocket->bind(QHostAddress::Any,port);
    connect(udpsocket,SIGNAL(readyRead()),this,SLOT(readyReadSlot()));


    QMutexLocker locker(&m_Mutex);
    if (m_OutPut != nullptr) delete m_OutPut;

    setFormat(quality);
    int sample=format.sampleRate();
    int bytes=format.sampleSize()/8;
    int channel=format.channelCount();
    frameLen=recv_audio_MS*sample*bytes*channel/1000;
    maxAudioLength=frameLen*1000;


    QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
    if (!info.isFormatSupported(format))// 判断是否支持配置
        format = info.nearestFormat(format);// 如果不支持，取最近的配置方法。

    m_OutPut = new QAudioOutput(format);
    m_AudioIo = m_OutPut->start();
    m_IsPlaying = true;
}

void RecvAudio::run(void)
{
    while (!this->isInterruptionRequested())
    {
        if (!m_IsPlaying)
            break;

        QMutexLocker locker(&m_Mutex);

        if(m_PCMDataBuffer.size() < m_CurrentPlayIndex + frameLen){//缓冲区不够播放60ms音频
            continue;
        }
        else{
            //拷贝960字节的数据
            char *writeData = new char[frameLen];
            memcpy(writeData,&m_PCMDataBuffer.data()[m_CurrentPlayIndex], frameLen);

            // 写入音频数据
            m_AudioIo->write(writeData, frameLen);
            m_CurrentPlayIndex += frameLen;
            delete []writeData;

            //如果长度超过了MAX_AUDIO_LEN就从
            if(m_CurrentPlayIndex > maxAudioLength){
                m_PCMDataBuffer = m_PCMDataBuffer.right(m_PCMDataBuffer.size()-maxAudioLength);
                m_CurrentPlayIndex -= maxAudioLength;
            }
        }
    }
    m_PCMDataBuffer.clear();
}

// 添加数据
void RecvAudio::addAudioBuffer(char* pData, int len)
{
    QMutexLocker locker(&m_Mutex);
    m_PCMDataBuffer.append(pData, len);
}

void RecvAudio::cleanAllAudioBuffer(void)
{
    QMutexLocker locker(&m_Mutex);
    m_CurrentPlayIndex = 0;
    m_PCMDataBuffer.clear();
    m_IsPlaying = false;
}

void RecvAudio::readyReadSlot()
{
    while(udpsocket->hasPendingDatagrams())
    {
        QHostAddress senderip;
        quint16 senderport;
        char data[1024];
        memset(data,0,1024);
        int size = udpsocket->readDatagram(data,1024,&senderip,&senderport);
        addAudioBuffer(data, size);
    }
}

void RecvAudio::stop()
{
//    udpsocket->close();
    m_OutPut->stop();
    cleanAllAudioBuffer();
}

void RecvAudio::setFormat(int quality)
{
    format.setSampleSize(16);
    format.setCodec("audio/pcm");
    format.setByteOrder(QAudioFormat::LittleEndian);
    format.setSampleType(QAudioFormat::SignedInt);

    switch(quality){
        case 0:
            format.setSampleRate(48000);
            format.setChannelCount(2);
            break;
        case 1:
            format.setSampleRate(44100);
            format.setChannelCount(2);
            break;
        case 2:
            format.setSampleRate(16000);
            format.setChannelCount(2);
            break;
        case 3:
            format.setSampleRate(8000);
            format.setChannelCount(2);
            break;
        case 4:
            format.setSampleRate(48000);
            format.setChannelCount(1);
            break;
        case 5:
            format.setSampleRate(44100);
            format.setChannelCount(1);
            break;
        case 6:
            format.setSampleRate(16000);
            format.setChannelCount(1);
            break;
        case 7:
            format.setSampleRate(8000);
            format.setChannelCount(1);
            break;
        default:
            format.setSampleRate(8000);
            format.setChannelCount(1);
    }
}

